package com.ideaaedi.zoo.example.springboot.websocket.endpoint;

import cn.hutool.core.util.RandomUtil;
import com.ideaaedi.commonds.time.DateTimeConverter;
import com.ideaaedi.zoo.commonbase.constant.ZooConstant;
import com.ideaaedi.zoo.diy.artifact.websocket.core.AbstractWebSocketEndpoint;
import com.ideaaedi.zoo.diy.artifact.websocket.core.KeepWebSocketHeaders;
import jakarta.websocket.OnMessage;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * demo websocket服务端点
 * <br />
 * 注：如果配置有spring-security之类的全局认证拦截器的话，记得放行websocket相关的endpoint
 *
 * @author <font size = "20" color = "#3CAA3C"><a href="https://gitee.com/JustryDeng">JustryDeng</a></font> <img
 * src="https://gitee.com/JustryDeng/shared-files/raw/master/JustryDeng/avatar.jpg" />
 * @since 1.0.0
 */
@Slf4j
@Component
@ServerEndpoint(value = "/ws-endpoint/demo", configurator = KeepWebSocketHeaders.class)
public class DemoWsEndpoint extends AbstractWebSocketEndpoint implements ApplicationRunner {
    
    /**
     * 服务端收到消息
     */
    @Override
    @OnMessage
    public void onMessage(String message, @Nonnull Session session) {
        String traceXd = null;
        try {
            traceXd = (String)session.getUserProperties().get(ZooConstant.TRACE_XD);
        } catch (Exception ignore) {
        }
        try (MDC.MDCCloseable ignored = MDC.putCloseable(ZooConstant.TRACE_XD, traceXd)) {
            log.info("received message. id -> {}, path -> {}, userProperties -> {}, message -> {}",
                    session.getId(), session.getRequestURI().getPath(), session.getUserProperties(), message);
            sendMessageLocal(session, "received message success. message is -> " + message);
        }
    }
    
    /**
     * 测试
     */
    @Override
    public void run(ApplicationArguments args) {
        // 服务端随机给客户端发送测试消息
        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        executor.scheduleAtFixedRate(() -> {
            List<String> keys = new ArrayList<>(CLIENT_SESSION_MAP.keySet());
            if (!CollectionUtils.isEmpty(keys)) {
                Collections.shuffle( keys);
                String randomClientSessionUuid = keys.get(0);
                sendMessageLocal(randomClientSessionUuid, "服务端随机给客户端发送的测试消息：" + DateTimeConverter.REGULAR_DATE_TIME.now() + "@" + RandomUtil.randomString(10));
            }
        }, 0, 10, TimeUnit.SECONDS);
    }
}
